﻿using CKS.PLC.Core.Siemens;
using FreeSql.DataAnnotations;
using FreeSql.Internal.Model;
using Infrastructure;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Infrastructure;
using ZR.Model.Models.ProductionControl;

namespace CKS.PLC.Core.Cache
{
    public static class ServiceCommon
    {
        public static SafeList<ISiemensClient> PlcClients { get;  set; }=new SafeList<ISiemensClient>();


        public static object _lock = new object();
        private static ConcurrentDictionary<string,object> dicLock = new ConcurrentDictionary<string,object>();
        public static Dictionary<string, TableInfo> TableDics = new Dictionary<string, TableInfo>();
        public static Dictionary<string, List<CksVirtualColumn>> ColDic = new Dictionary<string, List<CksVirtualColumn>>();

        public static object GetLockObj(string lockkey) 
        { 
            if (!dicLock.ContainsKey(lockkey))
                dicLock[lockkey] = new object();
            return dicLock[lockkey];
        }

        public static TableInfo GetFreesqlTableInfo(CksVirtualTable vt, List<CksVirtualColumn> vcs, bool UseCache = true)
        {
            var tableName = $"cks_t_{vt.TableName}";

            string className = $"Model_{Guid.NewGuid().ToString("N")}";



            lock (GetLockObj("GetFreesqlTableInfo"))
            {
                bool isChange = false;
                if (UseCache)
                {
                    if (TableDics.ContainsKey(tableName))
                    {
                        var cTable = TableDics[tableName];
                        //判断缓存的列是否变化
                        var oldCols = ColDic[tableName];
                        //
                        if (!HasDifferentIds(oldCols, vcs)) //不存在不同id 则说明列的数量和ID无变化
                        {                                   //接下来检查列名称是否变化
                            foreach (var col in vcs)
                            {
                                var old = oldCols.Find(a => a.Id == col.Id);
                                if (old == null || !old.ColumnName.Equals(col.ColumnName))
                                {
                                    isChange = true;
                                }
                            }
                        }
                        else
                        {
                            isChange = true;
                        }

                        if (!isChange)
                        {
                            return cTable; //无变化返回缓存
                        }


                    }
                }
                List<Attribute> attributes = new List<Attribute>();
                attributes.Add(new TableAttribute { Name = tableName });
                var mainc = vcs.Find(a => a.IsPrimary);
                if (mainc != null)
                    attributes.Add(new IndexAttribute($"index_{tableName}_{mainc.ColumnName}", $"{mainc.ColumnName}"));
                var tableBuilder = InternalApp.Fsql.CodeFirst.DynamicEntity(className,
                    attributes.ToArray()
                    );
                tableBuilder.Property("Id", typeof(long), new ColumnAttribute() { IsIdentity = true, IsPrimary = true });
                foreach (var item in vcs)
                {
                    if (item.IsPrimary)
                        tableBuilder.Property(item.ColumnName, typeof(string), new ColumnAttribute() { StringLength = 50 });
                    else
                        tableBuilder.Property(item.ColumnName, typeof(string), new ColumnAttribute() { StringLength = 50 });
                }
                tableBuilder.Property("CreatedTime", typeof(DateTime));
                tableBuilder.Property("Nullity", typeof(bool)); //是否禁用，禁用代表无效
                tableBuilder.Property("IsDeleted", typeof(bool)); //是否软删除
                var table = tableBuilder.Build();

                if (UseCache)
                {
                    TableDics[tableName] = table;
                    ColDic[tableName] = vcs;
                }
                return table;

            }


        }

        // 判断两个列表中是否存在ID不一致的元素
        public static bool HasDifferentIds(List<CksVirtualColumn> list1, List<CksVirtualColumn> list2)
        {
            // 首先检查两个列表的元素数量是否相同
            if (list1.Count != list2.Count)
                return true; // 数量不同，肯定存在不一致

            // 获取两个列表的ID集合
            var ids1 = list1.Select(item => item.Id).ToList();
            var ids2 = list2.Select(item => item.Id).ToList();

            // 排序后比较每个位置的ID是否相同
            ids1.Sort();
            ids2.Sort();

            for (int i = 0; i < ids1.Count; i++)
            {
                if (ids1[i] != ids2[i])
                    return true; // 发现ID不一致
            }

            return false; // 所有ID都一致
        }

        
    }
}
